/*
 * Copyright (c) 2009. Silenus Consultoria, S.L.
 */
package es.silenus.detecta.dao.impl;

import es.silenus.detecta.dao.ReadWriteDAO;

import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collection;


/**
 * Read write DAO implementation.
 *
 * @author <a href="mailto:malonso@silenus-consultoria.es">Mariano Alonso</a>
 *
 * @param <T> the element.
 * @param <K> the key.
 *
 * @since 25-mar-2009 11:02:51
 */
public class ReadWriteDAOImpl<T, K> extends ReadDAOImpl<T, K> implements ReadWriteDAO<T, K> {
	/**
	 * Makes an object instance persistent.
	 *
	 * @param object an object instance.
	 *
	 * @return the key.
	 */
	@SuppressWarnings("unchecked")
	@Transactional(propagation = Propagation.REQUIRED)
	public K save(final T object) {
		if(object != null) {
			if(entityName != null) {
				return (K)getHibernateTemplate().save(entityName, object);
			} else {
				return (K)getHibernateTemplate().save(object);
			}
		}

		return null;
	}

	/**
	 * Updates a persistent object instance.
	 *
	 * @param object a persistent object instance.
	 *
	 * @return the element.
	 */
	@Transactional(propagation = Propagation.REQUIRED)
	public T update(final T object) {
		if(object != null) {
			if(entityName != null) {
				getHibernateTemplate().update(entityName, object);
			} else {
				getHibernateTemplate().update(object);
			}
		}

		return object;
	}

	/**
	 * Removes a persistent object instance.
	 *
	 * @param object a persistent object instance.
	 */
	@Transactional(propagation = Propagation.REQUIRED)
	public void remove(final T object) {
		if(object != null) {
			if(entityName != null) {
				getHibernateTemplate().delete(entityName, object);
			} else {
				getHibernateTemplate().delete(object);
			}
		}
	}

	/**
	 * Removes some persistent objects.
	 *
	 * @param objects the persistent objects.
	 */
	@Transactional(propagation = Propagation.REQUIRED)
	public void remove(final T[] objects) {
		if(objects != null) {
			if(entityName != null) {
				for(T o : objects) {
					getHibernateTemplate().delete(entityName, o);
				}
			} else {
				for(T o : objects) {
					getHibernateTemplate().delete(o);
				}
			}
		}
	}

	/**
	 * Removes some persistent objects.
	 *
	 * @param objects the persistent objects.
	 */
	@Transactional(propagation = Propagation.REQUIRED)
	public void remove(final Collection<T> objects) {
		if(objects != null) {
			if(entityName != null) {
				for(T o : objects) {
					getHibernateTemplate().delete(entityName, o);
				}
			} else {
				for(T o : objects) {
					getHibernateTemplate().delete(o);
				}
			}
		}
	}

	/**
	 * Removes a persistent object by its key.
	 *
	 * @param key the persistent object key.
	 */
	@Transactional(propagation = Propagation.REQUIRED)
	public void removeByKey(final K key) {
		remove(findById(key));
	}

	/**
	 * Removes some persistent objects by their keys.
	 *
	 * @param keys the persistent object keys.
	 */
	@Transactional(propagation = Propagation.REQUIRED)
	public void removeByKey(final K[] keys) {
		remove(findByIds(keys));
	}

	/**
	 * Removes some persistent objects by their keys.
	 *
	 * @param keys the persistent object keys.
	 */
	@Transactional(propagation = Propagation.REQUIRED)
	public void removeByKey(final Collection<K> keys) {
		remove(findByIds(keys));
	}
}
